library(data.table)
library(ggplot2)
Registered S3 method overwritten by 'dplyr':
  method           from
  print.rowwise_df     
library(beanplot) # for beanplots
library(gridExtra) # to combine ggplots together
library(grid) # to combine ggplots together


knitr::opts_knit$set(root.dir = rprojroot::find_rstudio_root_file()) # tell RStudio to use project root directory as the root for this notebook. Needed since we are storing code in a separate directory.

Load data

# BioTime
load('data/biotime_blowes/bt_malin.Rdata')
bt <- data.table(bt_malin); rm(bt_malin)

# Temperature average, trends, and seasonality
temperature <- fread('output/temperature_byrarefyID.csv.gz')

# microclimates
microclim <- fread('output/microclimates.csv.gz', drop = 1)

# NPP
npp <- fread('output/npplandocean.csv.gz')

# Body size
bs <- fread('output/mass_byrarefyid.csv.gz', drop = 1)
bs[, ':='(STUDY_ID = NULL, REALM = NULL, taxa_mod = NULL)] # remove unnecessary columns 

# Mobility
speed <- fread('output/speed_byrarefyID.csv.gz', drop = 1)
speed[, ':='(STUDY_ID = NULL, REALM = NULL, taxa_mod = NULL)] # remove unnecessary columns 

# Lifespan
lsp <- fread('output/lifespan_byrarefyID.csv.gz')

# CTI
cti <- fread('output/cti_byrarefyID.csv.gz')
    
# consumer vs. producer
consfrac <- fread('output/consfrac_byrarefyID.csv.gz')

# richness
rich <- fread('output/richness_by_rarefyID.csv.gz') # number of species

# endotherm vs. ectotherm
endofrac <- fread('output/endofrac_byrarefyID.csv.gz') # endotherm vs. ectotherm classifications

# human impact
human <- fread('output/humanimpact_by_rarefyID.csv.gz')

# %veg
veg <- as.data.table(readRDS('output/vct_by_rarefyID.rds'))
veg[, veg := (`tree cover % (mean)` + 0.5 * `non-tree veg. % (mean)`)/100] # veg index from 0 (all non-veg) to 1 (all tree). Non-tree veg counts as 0.5.

Plot a turnover example

First is a long time-series, next one shows an example result of removing the first year of self-comparison.

#bt[, .(n = .N), by = rarefyID][n > 50,]

ggplot(bt[rarefyID == '339_1085477'], aes(YEAR, Jtu_base)) +
    geom_point() +
    geom_smooth(method = 'lm') +
    xlab('Year') + ylab('Jaccard dissimilarity')


ggplot(bt[rarefyID == '489_16754'], aes(YEAR, Jtu_base)) +
    geom_point() +
    geom_smooth(method = 'lm', se = FALSE) +
    xlab('Year') + ylab('Jaccard dissimilarity') +
  geom_smooth(data = bt[rarefyID == '489_16754' & YEAR != 2000], method = 'lm', se = FALSE, color = 'red')

Compare covariates across realms

i <- trends[, !duplicated(rarefyID)]; sum(i)
[1] 53013
par(mfrow=c(5,3))
beanplot(rarefyID_y ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Latitude (degN)', ll = 0.05)
beanplot(tempave ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Temperature (degC)', ll = 0.05)
beanplot(tempave_metab ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Metabolic Temperature (degC)', ll = 0.05, bw = 'nrd0') # nrd0 bandwidth to calculation gap
beanplot(seas ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Seasonality (degC)', ll = 0.05)
beanplot(microclim ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Microclimates (degC)', ll = 0.05)
log="y" selected
beanplot(temptrend ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Temperature trend (degC/yr)', ll = 0.05)
beanplot(mass_mean_weight ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Mass (g)', ll = 0.05, log = 'y')
beanplot(speed_mean_weight +1 ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Speed (km/hr)', ll = 0.05, log = 'y')
beanplot(lifespan_mean_weight ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Lifespan (yr)', ll = 0.05, log = 'y')
#beanplot(consfrac ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Consumers (fraction)', ll = 0.05, log = '') # too sparse
#beanplot(endofrac ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Endotherms (fraction)', ll = 0.05, log = '') # too sparse
beanplot(Nspp ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Number of species', ll = 0.05, log = 'y')
beanplot(thermal_bias ~ REALM, data = trends[i & !is.na(thermal_bias),], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Thermal bias (degC)', ll = 0.05)
beanplot(npp ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'NPP', ll = 0.05)
log="y" selected
beanplot(veg ~ REALM, data = trends[i & REALM !='Marine',], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'NPP', ll = 0.05)

Marine are in generally warmer locations (seawater doesn’t freeze) Marine have much lower seasonality. Marine and freshwater have some very small masses (plankton), but much of dataset is similar to terrestrial. Marine has a lot of slow, crawling organisms, but land has plants. Land also has birds (fast).

Plot turnover vs. temperature

Time-series length and temperature trend?

ggplot(trends, aes(temptrend, nyrBT)) +
  geom_point() +
  geom_smooth() +
  scale_y_log10()

Plot turnover vs. explanatory variables

Lines are ggplot smoother fits.

Strong trends with temperature change, but trends are pretty symmetric around no trend in temperature, which implies warming or cooling drives similar degree of community turnover. Some indication of less turnover for larger organisms (mass) Higher turnover on land with higher seasonality? More turnover for shorter-lived organisms? No really clear differences among realms.

Write out

write.csv(trends, gzfile('output/turnover_w_covariates.csv.gz'), row.names = FALSE)

Useful variables

# realm that combined Terrestrial and Freshwater, for interacting with human impact
trends[, REALM2 := REALM]
levels(trends$REALM2) = list(TerrFresh = "Freshwater", TerrFresh = "Terrestrial", Marine = "Marine")

# group Marine invertebrates/plants in with All
trends[, taxa_mod2 := taxa_mod]
trends[taxa_mod == 'Marine invertebrates/plants', taxa_mod2 := 'All']

Log-transform some variables, then center and scale.

trends[, tempave.sc := scale(tempave)]
trends[, tempave_metab.sc := scale(tempave_metab)]
trends[, seas.sc := scale(seas)]
trends[, microclim.sc := scale(log(microclim))]
trends[, temptrend.sc := scale(temptrend, center = FALSE)]
trends[, temptrend_abs.sc := scale(abs(temptrend), center = FALSE)] # do not center, so that 0 is still 0 temperature change
trends[, mass.sc := scale(log(mass_mean_weight))]
trends[, speed.sc := scale(log(speed_mean_weight+1))]
trends[, lifespan.sc := scale(log(lifespan_mean_weight))]
trends[, consumerfrac.sc := scale(consfrac)]
trends[, endothermfrac.sc := scale(endofrac)]
trends[, nspp.sc := scale(log(Nspp))]
trends[, thermal_bias.sc := scale(thermal_bias)]
trends[, npp.sc := scale(log(npp))]
trends[, veg.sc := scale(log(veg+1))]
trends[, human_bowler.sc := scale(log(human_bowler+1)), by = REALM2] # separate scaling by realm
trends[REALM2 == 'TerrFresh', human_footprint.sc := scale(log(human_venter+1))]
trends[REALM2 == 'Marine', human_footprint.sc := scale(log(human_halpern))]

Do the variables look ok?

Unscaled

# histograms to examine
cexmain = 0.6
par(mfrow = c(5,4))
invisible(trends[, hist(minyrBT, main = 'Start year', cex.main = cexmain)])
invisible(trends[, hist(maxyrBT - minyrBT, main = 'Duration (years)', cex.main = cexmain)])
invisible(trends[, hist(nyrBT, main = 'Number of sampled years', cex.main = cexmain)])
invisible(trends[, hist(mass_mean_weight, main = 'Mass (g)', cex.main = cexmain)])
invisible(trends[, hist(speed_mean_weight, main = 'Speed (km/hr)', cex.main = cexmain)])
invisible(trends[, hist(lifespan_mean_weight, main = 'Lifespan (yr)', cex.main = cexmain)])
invisible(trends[, hist(tempave_metab, main = 'Metabolic temperature (°C)', cex.main = cexmain)])
invisible(trends[, hist(consfrac, main = 'Consumers (fraction)', cex.main = cexmain)])
invisible(trends[, hist(endofrac, main = 'Endotherms (fraction)', cex.main = cexmain)])
invisible(trends[, hist(tempave, main = 'Environmental temperature (°C)', cex.main = cexmain)])
invisible(trends[, hist(temptrend, main = 'Temperature trend (°C/yr)', cex.main = cexmain)])
invisible(trends[, hist(seas, main = 'Seasonality (°C)', cex.main = cexmain)])
invisible(trends[, hist(microclim, main = 'Microclimates (°C)', cex.main = cexmain)])
invisible(trends[, hist(Nspp, main = 'Species richness', cex.main = cexmain)])
invisible(trends[, hist(thermal_bias, main = 'Thermal bias (°C)', cex.main = cexmain)])
invisible(trends[, hist(npp, main = 'Net primary productivity', cex.main = cexmain)])
invisible(trends[, hist(veg, main = 'Vegetation index', cex.main = cexmain)])
invisible(trends[, hist(human_bowler, main = 'Human impact score (Bowler)', cex.main = cexmain)])
invisible(trends[, hist(human_venter, main = 'Human impact score (Venter)', cex.main = cexmain)])
invisible(trends[, hist(human_halpern, main = 'Human impact score (Halpern)', cex.main = cexmain)])

Scaled

# histograms to examine
cexmain = 0.6
par(mfrow = c(5,4))
invisible(trends[, hist(tempave.sc, main = 'Environmental temperature (°C)', cex.main = cexmain)])
invisible(trends[, hist(tempave_metab.sc, main = 'Metabolic temperature (°C)', cex.main = cexmain)])
invisible(trends[, hist(seas.sc, main = 'Seasonality (°C)', cex.main = cexmain)])
invisible(trends[, hist(microclim.sc, main = 'log Microclimates (°C)', cex.main = cexmain)])
invisible(trends[, hist(temptrend.sc, main = 'Temperature trend (°C/yr)', cex.main = cexmain)])
invisible(trends[, hist(temptrend_abs.sc, main = 'abs(Temperature trend) (°C/yr)', cex.main = cexmain)])
invisible(trends[, hist(mass.sc, main = 'log Mass (g)', cex.main = cexmain)])
invisible(trends[, hist(speed.sc, main = 'log Speed (km/hr)', cex.main = cexmain)])
invisible(trends[, hist(lifespan.sc, main = 'log Lifespan (yr)', cex.main = cexmain)])
invisible(trends[, hist(consumerfrac.sc, main = 'Consumers (fraction)', cex.main = cexmain)])
invisible(trends[, hist(endothermfrac.sc, main = 'Endotherms (fraction)', cex.main = cexmain)])
invisible(trends[, hist(nspp.sc, main = 'log Species richness', cex.main = cexmain)])
invisible(trends[, hist(thermal_bias.sc, main = 'Thermal bias (°C)', cex.main = cexmain)])
invisible(trends[, hist(npp.sc, main = 'log Net primary productivity', cex.main = cexmain)])
invisible(trends[, hist(veg.sc, main = 'log Vegetation index', cex.main = cexmain)])
invisible(trends[, hist(human_bowler.sc, main = 'log Human impact score (Bowler)', cex.main = cexmain)])
invisible(trends[, hist(human_footprint.sc, main = 'log Human impact score (Venter & Halpern)', cex.main = cexmain)])

Check correlations among variables. Pearson’s r is on the lower diagonal.

panel.cor <- function(x, y, digits = 2, prefix = "", cex.cor, ...)
{
    usr <- par("usr"); on.exit(par(usr))
    par(usr = c(0, 1, 0, 1))
    r <- cor(x, y, use = 'pairwise.complete.obs')
    txt <- format(c(r, 0.123456789), digits = digits)[1]
    txt <- paste0(prefix, txt)
    if(missing(cex.cor)) cex.cor <- 0.8/strwidth(txt)
    text(0.5, 0.5, txt) #, cex = cex.cor * r)
}
pairs(formula = ~ tempave.sc + tempave_metab.sc + seas.sc + microclim.sc + temptrend.sc + temptrend_abs.sc + mass.sc + speed.sc + lifespan.sc + consumerfrac.sc + endothermfrac.sc + nspp.sc + thermal_bias.sc + npp.sc + veg.sc + human_bowler.sc + human_footprint.sc, data = trends, gap = 1/10, cex = 0.2, col = '#00000022', lower.panel = panel.cor)

Mass and lifespan look tightly correlated, but r only 0.56…? Tempave_metab and lifespan don’t look tightly correlated, but r= -0.81 Tempave_metab and speed don’t look tightly correlated, but r= -0.83 Lifespan and speed don’t look tightly correlated, but r = 0.73

LS0tCnRpdGxlOiAiVHVybm92ZXIgY292YXJpYXRlIGRhdGEgcHJlcCIKb3V0cHV0OgogIGdpdGh1Yl9kb2N1bWVudDogZGVmYXVsdAogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKLS0tCgpgYGB7ciBzZXR1cH0KbGlicmFyeShkYXRhLnRhYmxlKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoYmVhbnBsb3QpICMgZm9yIGJlYW5wbG90cwpsaWJyYXJ5KGdyaWRFeHRyYSkgIyB0byBjb21iaW5lIGdncGxvdHMgdG9nZXRoZXIKbGlicmFyeShncmlkKSAjIHRvIGNvbWJpbmUgZ2dwbG90cyB0b2dldGhlcgoKCmtuaXRyOjpvcHRzX2tuaXQkc2V0KHJvb3QuZGlyID0gcnByb2pyb290OjpmaW5kX3JzdHVkaW9fcm9vdF9maWxlKCkpICMgdGVsbCBSU3R1ZGlvIHRvIHVzZSBwcm9qZWN0IHJvb3QgZGlyZWN0b3J5IGFzIHRoZSByb290IGZvciB0aGlzIG5vdGVib29rLiBOZWVkZWQgc2luY2Ugd2UgYXJlIHN0b3JpbmcgY29kZSBpbiBhIHNlcGFyYXRlIGRpcmVjdG9yeS4KYGBgCgojIyMgTG9hZCBkYXRhCmBgYHtyIGxvYWQgZGF0YX0KIyBCaW9UaW1lCmxvYWQoJ2RhdGEvYmlvdGltZV9ibG93ZXMvYnRfbWFsaW4uUmRhdGEnKQpidCA8LSBkYXRhLnRhYmxlKGJ0X21hbGluKTsgcm0oYnRfbWFsaW4pCgojIFRlbXBlcmF0dXJlIGF2ZXJhZ2UsIHRyZW5kcywgYW5kIHNlYXNvbmFsaXR5CnRlbXBlcmF0dXJlIDwtIGZyZWFkKCdvdXRwdXQvdGVtcGVyYXR1cmVfYnlyYXJlZnlJRC5jc3YuZ3onKQoKIyBtaWNyb2NsaW1hdGVzCm1pY3JvY2xpbSA8LSBmcmVhZCgnb3V0cHV0L21pY3JvY2xpbWF0ZXMuY3N2Lmd6JywgZHJvcCA9IDEpCgojIE5QUApucHAgPC0gZnJlYWQoJ291dHB1dC9ucHBsYW5kb2NlYW4uY3N2Lmd6JykKCiMgQm9keSBzaXplCmJzIDwtIGZyZWFkKCdvdXRwdXQvbWFzc19ieXJhcmVmeWlkLmNzdi5neicsIGRyb3AgPSAxKQpic1ssICc6PScoU1RVRFlfSUQgPSBOVUxMLCBSRUFMTSA9IE5VTEwsIHRheGFfbW9kID0gTlVMTCldICMgcmVtb3ZlIHVubmVjZXNzYXJ5IGNvbHVtbnMgCgojIE1vYmlsaXR5CnNwZWVkIDwtIGZyZWFkKCdvdXRwdXQvc3BlZWRfYnlyYXJlZnlJRC5jc3YuZ3onLCBkcm9wID0gMSkKc3BlZWRbLCAnOj0nKFNUVURZX0lEID0gTlVMTCwgUkVBTE0gPSBOVUxMLCB0YXhhX21vZCA9IE5VTEwpXSAjIHJlbW92ZSB1bm5lY2Vzc2FyeSBjb2x1bW5zIAoKIyBMaWZlc3Bhbgpsc3AgPC0gZnJlYWQoJ291dHB1dC9saWZlc3Bhbl9ieXJhcmVmeUlELmNzdi5neicpCgojIENUSQpjdGkgPC0gZnJlYWQoJ291dHB1dC9jdGlfYnlyYXJlZnlJRC5jc3YuZ3onKQogICAgCiMgY29uc3VtZXIgdnMuIHByb2R1Y2VyCmNvbnNmcmFjIDwtIGZyZWFkKCdvdXRwdXQvY29uc2ZyYWNfYnlyYXJlZnlJRC5jc3YuZ3onKQoKIyByaWNobmVzcwpyaWNoIDwtIGZyZWFkKCdvdXRwdXQvcmljaG5lc3NfYnlfcmFyZWZ5SUQuY3N2Lmd6JykgIyBudW1iZXIgb2Ygc3BlY2llcwoKIyBlbmRvdGhlcm0gdnMuIGVjdG90aGVybQplbmRvZnJhYyA8LSBmcmVhZCgnb3V0cHV0L2VuZG9mcmFjX2J5cmFyZWZ5SUQuY3N2Lmd6JykgIyBlbmRvdGhlcm0gdnMuIGVjdG90aGVybSBjbGFzc2lmaWNhdGlvbnMKCiMgaHVtYW4gaW1wYWN0Cmh1bWFuIDwtIGZyZWFkKCdvdXRwdXQvaHVtYW5pbXBhY3RfYnlfcmFyZWZ5SUQuY3N2Lmd6JykKCiMgJXZlZwp2ZWcgPC0gYXMuZGF0YS50YWJsZShyZWFkUkRTKCdvdXRwdXQvdmN0X2J5X3JhcmVmeUlELnJkcycpKQp2ZWdbLCB2ZWcgOj0gKGB0cmVlIGNvdmVyICUgKG1lYW4pYCArIDAuNSAqIGBub24tdHJlZSB2ZWcuICUgKG1lYW4pYCkvMTAwXSAjIHZlZyBpbmRleCBmcm9tIDAgKGFsbCBub24tdmVnKSB0byAxIChhbGwgdHJlZSkuIE5vbi10cmVlIHZlZyBjb3VudHMgYXMgMC41LgpgYGAKCiMjIyBQbG90IGEgdHVybm92ZXIgZXhhbXBsZQpGaXJzdCBpcyBhIGxvbmcgdGltZS1zZXJpZXMsIG5leHQgb25lIHNob3dzIGFuIGV4YW1wbGUgcmVzdWx0IG9mIHJlbW92aW5nIHRoZSBmaXJzdCB5ZWFyIG9mIHNlbGYtY29tcGFyaXNvbi4KYGBge3IgcGxvdCB0dXJub3Zlcn0KI2J0WywgLihuID0gLk4pLCBieSA9IHJhcmVmeUlEXVtuID4gNTAsXQoKZ2dwbG90KGJ0W3JhcmVmeUlEID09ICczMzlfMTA4NTQ3NyddLCBhZXMoWUVBUiwgSnR1X2Jhc2UpKSArCiAgICBnZW9tX3BvaW50KCkgKwogICAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJykgKwogICAgeGxhYignWWVhcicpICsgeWxhYignSmFjY2FyZCBkaXNzaW1pbGFyaXR5JykKCmdncGxvdChidFtyYXJlZnlJRCA9PSAnNDg5XzE2NzU0J10sIGFlcyhZRUFSLCBKdHVfYmFzZSkpICsKICAgIGdlb21fcG9pbnQoKSArCiAgICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEZBTFNFKSArCiAgICB4bGFiKCdZZWFyJykgKyB5bGFiKCdKYWNjYXJkIGRpc3NpbWlsYXJpdHknKSArCiAgZ2VvbV9zbW9vdGgoZGF0YSA9IGJ0W3JhcmVmeUlEID09ICc0ODlfMTY3NTQnICYgWUVBUiAhPSAyMDAwXSwgbWV0aG9kID0gJ2xtJywgc2UgPSBGQUxTRSwgY29sb3IgPSAncmVkJykKYGBgCgojIyMgQXNzZW1ibGUgZGF0YXNldCBvZiBiZXRhIGRpdmVyc2l0eSB0cmVuZHMgKHRlbXBvcmFsIHR1cm5vdmVyKSBhbmQgY292YXJpYXRlcwpgYGB7ciBhc3NlbWJsZSB0cmVuZHN9CiMgY2FsY3VsYXRlIHRlbXBvcmFsIHR1cm5vdmVyCmNhbGN0cmVuZCA8LSBmdW5jdGlvbih5LCBZRUFSLCBubSA9ICd5Jyl7ICMgZnVuY3Rpb24gdG8gY2FsYyB0cmVuZHMKICAjIHR1cm4gb2ZmIHdhcm5pbmdzIGZvciB0aGUgZm9sbG93aW5nCiAgZGVmYXVsdFcgPC0gZ2V0T3B0aW9uKCJ3YXJuIikKICBvcHRpb25zKHdhcm4gPSAtMSkKICAKICBtb2QgPC0gbG0oeSB+IFlFQVIpCiAgb3V0IDwtIGxpc3QoeSA9IGNvZWYobW9kKVsyXSwgIyBjb2VmIGZvciB0aGUgc2xvcGUKICAgICAgICAgICAgICB5X3NlID0gc3FydChkaWFnKHZjb3YobW9kKSkpWzJdKSAjIFNFCiAgbmFtZXMob3V0KSA8LSBjKG5tLCBwYXN0ZTAobm0sICdfc2UnKSkKICBvcHRpb25zKHdhcm4gPSBkZWZhdWx0VykKICByZXR1cm4ob3V0KQp9CgojIGZ1bmN0aW9uIHRvIGNhbGMgdHJlbmRzLCByZW1vdmluZyBmaXJzdCB5ZWFyIHdpdGggMApjYWxjdHJlbmRyZW0wIDwtIGZ1bmN0aW9uKHksIFlFQVIsIG5tID0gJ3knKXsKICAjIHR1cm4gb2ZmIHdhcm5pbmdzIGZvciB0aGUgZm9sbG93aW5nCiAgZGVmYXVsdFcgPC0gZ2V0T3B0aW9uKCJ3YXJuIikKICBvcHRpb25zKHdhcm4gPSAtMSkKICAKICBpZihsZW5ndGgoWUVBUik+Mil7CiAgICBvIDwtIG9yZGVyKFlFQVIpCiAgICBZRUFSMiA8LSBZRUFSW29dWzI6bGVuZ3RoKFlFQVIpXQogICAgeTIgPC0geVtvXVsyOmxlbmd0aCh5KV0KICAgIAogICAgaWYoc3VtKCFpcy5uYSh5MikpID49IDIpeyAjIG1ha2Ugc3VyZSBlbm91Z2ggdmFsdWVzIHRvIGZpdCBhIGxpbmUKICAgICAgbW9kIDwtIGxtKHkyIH4gWUVBUjIpCiAgICAgIG91dCA8LSBsaXN0KHkgPSBjb2VmKG1vZClbMl0sICMgY29lZiBmb3IgdGhlIHNsb3BlCiAgICAgICAgICAgICAgICAgIHlfc2UgPSBzcXJ0KGRpYWcodmNvdihtb2QpKSlbMl0pICMgU0UKICAgICAgbmFtZXMob3V0KSA8LSBjKG5tLCBwYXN0ZTAobm0sICdfc2UnKSkKICAgICAgb3B0aW9ucyh3YXJuID0gZGVmYXVsdFcpCiAgICAgIHJldHVybihvdXQpCiAgICAgIAogICAgfSBlbHNlIHsKICAgICAgb3V0IDwtIGxpc3QoeSA9IE5BX3JlYWxfLCB5X3NlID0gTkFfcmVhbF8pCiAgICAgIG5hbWVzKG91dCkgPC0gYyhubSwgcGFzdGUwKG5tLCAnX3NlJykpCiAgICAgIAogICAgICBvcHRpb25zKHdhcm4gPSBkZWZhdWx0VykKICAgICAgcmV0dXJuKG91dCkKICAgIH0KICAgIAogIH0gZWxzZSB7CiAgICBvdXQgPC0gbGlzdCh5ID0gTkFfcmVhbF8sIHlfc2UgPSBOQV9yZWFsXykKICAgIG5hbWVzKG91dCkgPC0gYyhubSwgcGFzdGUwKG5tLCAnX3NlJykpCiAgCiAgICBvcHRpb25zKHdhcm4gPSBkZWZhdWx0VykKICAgIHJldHVybihvdXQpCiAgfQogIAoKfQoKCnNldGtleShidCwgU1RVRFlfSUQsIHJhcmVmeUlELCBZRUFSKQoKCnRyZW5kcyA8LSBidFssIGNhbGN0cmVuZChKdHVfYmFzZSwgWUVBUiwgJ0p0dXRyZW5kJyksIAogICAgYnkgPSAuKFJFQUxNLCBCaW9tZSwgdGF4YV9tb2QsIFNUVURZX0lELCByYXJlZnlJRCwgcmFyZWZ5SURfeCwgcmFyZWZ5SURfeSldICMgY2FsY3VsYXRlIHRyZW5kIGluIEphY2NhcmQgdHVybm92ZXIgZnJvbSBmaXJzdCB5ZWFyLCBwbHVzIFNFcwp0cmVuZHMyIDwtIGJ0WywgY2FsY3RyZW5kKEpiZXRhX2Jhc2UsIFlFQVIsICdKYmV0YXRyZW5kJyksIAogICAgYnkgPSAuKHJhcmVmeUlEKV0gIyBjYWxjdWxhdGUgdHJlbmQgaW4gdG90YWwgSmFjY2FyZCcgYmV0YSBkaXZlcnNpdHkncyBmcm9tIGZpcnN0IHllYXIsIAp0cmVuZHMzIDwtIGJ0WywgY2FsY3RyZW5kKDEtSG9ybl9iYXNlLCBZRUFSLCAnSG9ybnRyZW5kJyksIAogICAgYnkgPSAuKHJhcmVmeUlEKV0gIyBjYWxjdWxhdGUgdHJlbmQgaW4gSG9ybi1Nb3Jpc2l0YSBmcm9tIGZpcnN0IHllYXIuIENvbnZlcnQgdG8gZGlzc2ltaWxhcml0eS4KI3RyZW5kczQgPC0gYnRbLCAuKFN0cmVuZCA9IGNvZWYobG0oSShsb2coUykpIH4gWUVBUikpWzJdKSwgYnkgPSAuKHJhcmVmeUlEKV0gIyB0cmVuZCBpbiBsb2coUykKCnRyZW5kczUgPC0gYnRbLCBjYWxjdHJlbmRyZW0wKEp0dV9iYXNlLCBZRUFSLCAnSnR1dHJlbmRyZW0wJyksIAogICAgYnkgPSAuKHJhcmVmeUlEKV0gIyBjYWxjdWxhdGUgdHJlbmQgaW4gSmFjY2FyZCB0dXJub3ZlciB3aXRob3V0IGZpcnN0IHllYXIKdHJlbmRzNiA8LSBidFssIGNhbGN0cmVuZHJlbTAoSmJldGFfYmFzZSwgWUVBUiwgJ0piZXRhdHJlbmRyZW0wJyksIAogICAgYnkgPSAuKHJhcmVmeUlEKV0KdHJlbmRzNyA8LSBidFssIGNhbGN0cmVuZHJlbTAoMS1Ib3JuX2Jhc2UsIFlFQVIsICdIb3JudHJlbmRyZW0wJyksIAogICAgYnkgPSAuKHJhcmVmeUlEKV0KCgpueXJCVCA8LSAgYnRbLCAuKG55ckJUID0gbGVuZ3RoKFlFQVIpLCAKICAgICAgICAgICAgICAgICBtaW55ckJUID0gbWluKFlFQVIpLCAKICAgICAgICAgICAgICAgICBtYXh5ckJUID0gbWF4KFlFQVIpLAogICAgICAgICAgICAgICAgIG1lZGlhbnlyQlQgPSBtZWRpYW4oWUVBUiksCiAgICAgICAgICAgICAgICAgbWVhbnlyQlQgPSBtZWFuKFlFQVIpKSwgCiAgICAgICAgICAgICBieSA9IC4ocmFyZWZ5SUQpXSAjIG51bWJlciBvZiB5ZWFycyBpbiB0aW1lLXNlcmllcwoKdHJlbmRzIDwtIG1lcmdlKHRyZW5kcywgdHJlbmRzMikgIyBtZXJnZSBpbiB0b3RhbCBKIGFuZCBIb3JuLU1vcmlzaXRhCnRyZW5kcyA8LSBtZXJnZSh0cmVuZHMsIHRyZW5kczMpCnRyZW5kcyA8LSBtZXJnZSh0cmVuZHMsIHRyZW5kczUpCnRyZW5kcyA8LSBtZXJnZSh0cmVuZHMsIHRyZW5kczYpCnRyZW5kcyA8LSBtZXJnZSh0cmVuZHMsIHRyZW5kczcpCnRyZW5kcyA8LSBtZXJnZSh0cmVuZHMsIG55ckJUKQpgYGAKCkFkZCBjb3ZhcmlhdGVzCmBgYHtyIGFkZCBjb3ZhcmlhdGUgZGF0YX0KIyBhZGQgY292YXJpYXRlcwp0cmVuZHMgPC0gbWVyZ2UodHJlbmRzLCB0ZW1wZXJhdHVyZVssIC4ocmFyZWZ5SUQsIHRlbXBhdmUsIHRlbXBhdmVfbWV0YWIsIHRlbXB0cmVuZCwgc2VhcyldLCBhbGwueCA9IFRSVUUsIGJ5ID0gJ3JhcmVmeUlEJykgIyB0ZW1wZXJhdHVyZSBhdmUsIGF2ZSBtZXRhYm9saWMsIHRyZW5kLCBhbmQgc2Vhc29uYWxpdHkKdHJlbmRzIDwtIG1lcmdlKHRyZW5kcywgbWljcm9jbGltWywgLihyYXJlZnlJRCwgbWljcm9jbGltID0gVGVtcF9zZDIwa20pXSwgYWxsLnggPSBUUlVFLCBieSA9ICdyYXJlZnlJRCcpICMgbWljcm9jbGltYXRlcwp0cmVuZHMgPC0gbWVyZ2UodHJlbmRzLCBucHAsIGFsbC54ID0gVFJVRSwgYnkgPSAncmFyZWZ5SUQnKSAjIG5wcAp0cmVuZHMgPC0gbWVyZ2UodHJlbmRzLCBic1ssIC4ocmFyZWZ5SUQsIG1hc3NfbWVhbl93ZWlnaHQsIG1hc3Nfc2Rfd2VpZ2h0KV0sIGFsbC54ID0gVFJVRSkgIyBib2R5IHNpemUgbWFzcyAoZykKdHJlbmRzIDwtIG1lcmdlKHRyZW5kcywgc3BlZWRbLCAuKHJhcmVmeUlELCBzcGVlZF9tZWFuX3dlaWdodCwgc3BlZWRfc2Rfd2VpZ2h0KV0sIGFsbC54ID0gVFJVRSkgIyBzcGVlZCAoa20vaHIpCnRyZW5kcyA8LSBtZXJnZSh0cmVuZHMsIGxzcFssIC4ocmFyZWZ5SUQsIGxpZmVzcGFuX21lYW5fd2VpZ2h0LCBsaWZlc3Bhbl9zZF93ZWlnaHQpXSwgYWxsLnggPSBUUlVFKSAjIGxpZmVzcGFuICh5cikKdHJlbmRzIDwtIG1lcmdlKHRyZW5kcywgY3RpWywgLihyYXJlZnlJRCwgdGhlcm1hbF9iaWFzKV0sIGFsbC54ID0gVFJVRSkgIyB0aGVybWFsIGJpYXMgKGRlZ0MpCnRyZW5kcyA8LSBtZXJnZSh0cmVuZHMsIGNvbnNmcmFjWywgLihyYXJlZnlJRCwgY29uc2ZyYWMpXSwgYWxsLnggPSBUUlVFKSAjIGZyYWN0aW9uIGNvbnN1bWVycwp0cmVuZHMgPC0gbWVyZ2UodHJlbmRzLCByaWNoLCBhbGwueCA9IFRSVUUpICMgc3BlY2llcyByaWNobmVzcwp0cmVuZHMgPC0gbWVyZ2UodHJlbmRzLCBlbmRvZnJhY1ssIC4ocmFyZWZ5SUQsIGVuZG9mcmFjKV0sIGFsbC54ID0gVFJVRSkgIyBlbmRvdGhlcm0gdnMuIGVjdG90aGVybQp0cmVuZHMgPC0gbWVyZ2UodHJlbmRzLCBodW1hblssIC4ocmFyZWZ5SUQsIGh1bWFuX2Jvd2xlciA9IGF0YywgaHVtYW5fdmVudGVyID0gaGZwLCBodW1hbl9oYWxwZXJuID0gaGltcCldLCBhbGwueCA9IFRSVUUpICMgaHVtYW4gaW1wYWN0CnRyZW5kcyA8LSBtZXJnZSh0cmVuZHMsIHZlZ1ssIC4ocmFyZWZ5SUQsIHZlZyA9IHZlZyldLCBhbGwueCA9IFRSVUUpICMgdmVnZXRhdGlvbiBpbmRleAp0cmVuZHNbUkVBTE0gPT0gJ01hcmluZScsIHZlZyA6PSAwXSAjIHZlZyBpbmRleCBpcyAwIGF0IHNlYQpgYGAKCkRvIHNvbWUgYmFzaWMgY2hlY2tzIG9mIHRoZSB0dXJub3ZlciBjYWxjdWxhdGlvbnMKYGBge3IgYmFzaWMgY2hlY2tzfQojIGJhc2ljIGNoZWNrcwp0cmVuZHMKdHJlbmRzWywgLihtaW5KdHUgPSBtaW4oSnR1dHJlbmQpLCBtYXhKdHUgPSBtYXgoSnR1dHJlbmQpLCBtaW5KYmUgPSBtaW4oSmJldGF0cmVuZCksIG1heEpiZSA9IG1heChKYmV0YXRyZW5kKSwgCiAgICAgICAgICAgbWluSG8gPSBtaW4oSG9ybnRyZW5kLCBuYS5ybSA9IFRSVUUpLCBtYXhIbyA9IG1heChIb3JudHJlbmQsIG5hLnJtID0gVFJVRSkpLCBieSA9IFJFQUxNXQp0cmVuZHNbLCAuKG5KdHUgPSBzdW0oSnR1dHJlbmQgPCAwKSksIGJ5ID0gUkVBTE1dICMgd2h5IGFyZSBzb21lIHR1cm5vdmVyIHRyZW5kcyA8IDA/IGZpcnN0IHllYXIgbW9yZSBkaXZlcmdlZCB0aGFuIGZ1dHVyZSB5ZWFycwp0cmVuZHNbLCAuKG5KID0gc3VtKEp0dXRyZW5kID4gMCkpLCBieSA9IFJFQUxNXQoKIyBudW1iZXIgb2Ygc3BlY2llcwp0cmVuZHNbLCBzdW1tYXJ5KE5zcHApXQp0cmVuZHNbLCBwbG90KE5zcHAsIEp0dXRyZW5kLCBsb2cgPSAneCcpXQpgYGAKClJlbW92ZSBzdHVkaWVzIHdpdGggb25seSAxIHNwZWNpZXMKYGBge3IgcmVtb3ZlIDEtc3BwIHN0dWRpZXN9Cm5yb3codHJlbmRzKQp0cmVuZHMgPC0gdHJlbmRzW05zcHAgPiAxLCBdCm5yb3codHJlbmRzKQpgYGAKClR1cm5vdmVyIGNhbGN1bGF0aW9ucyBhcmUgY29ycmVsYXRlZCwgdGhvdWdoIGxlc3Mgc28gZm9yIEhvcm4KYGBge3IgYmFzaWMgcGFpcndpc2UgZ3JhcGhzIG9mIHR1cm5vdmVyIG1ldHJpY3N9CiMgYXJlIHR1cm5vdmVyIGNhbGN1bGF0aW9ucyBjb3JyZWxhdGVkPwpnZ3Bsb3QodHJlbmRzLCBhZXMoSmJldGF0cmVuZHJlbTAsIEp0dXRyZW5kcmVtMCkpICsKICAgIGdlb21fcG9pbnQoYWxwaGEgPSAwLjMpICsKICAgIGdlb21fc21vb3RoKCkKCmdncGxvdCh0cmVuZHMsIGFlcyhKYmV0YXRyZW5kcmVtMCwgSG9ybnRyZW5kcmVtMCkpICsKICAgIGdlb21fcG9pbnQoYWxwaGEgPSAwLjMpICsKICAgIGdlb21fc21vb3RoKCkKCmBgYApUZW1wb3JhbCB0dXJub3ZlciBpcyBub3QgYWxsIHRoYXQgY29ycmVsYXRlZCBiZXR3ZWVuIGluY2x1ZGluZyBmaXJzdCB5ZWFyIG9yIG5vdC4KYGBge3IgdHVybm92ZXIgbWV0cmljcyB3aXRoIGFuZCB3aXRob3V0IGZpcnN0IHllYXJ9CmdncGxvdCh0cmVuZHMsIGFlcyhKdHV0cmVuZCwgSnR1dHJlbmRyZW0wKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjMpICsKICBnZW9tX3Ntb290aCgpICsKICBnZW9tX2FibGluZShhID0gMCwgYiA9IDEpCgpnZ3Bsb3QodHJlbmRzLCBhZXMoSmJldGF0cmVuZCwgSmJldGF0cmVuZHJlbTApKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMykgKwogIGdlb21fc21vb3RoKCkgKwogIGdlb21fYWJsaW5lKGEgPSAwLCBiID0gMSkKCmdncGxvdCh0cmVuZHMsIGFlcyhIb3JudHJlbmQsIEhvcm50cmVuZHJlbTApKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMykgKwogIGdlb21fc21vb3RoKCkgKwogIGdlb21fYWJsaW5lKGEgPSAwLCBiID0gMSkKCmBgYAoKIyMgQ29tcGFyZSBjb3ZhcmlhdGVzIGFjcm9zcyByZWFsbXMKYGBge3IgY29tcGFyZSBhY3Jvc3MgcmVhbG1zLCBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9OX0KaSA8LSB0cmVuZHNbLCAhZHVwbGljYXRlZChyYXJlZnlJRCldOyBzdW0oaSkKcGFyKG1mcm93PWMoNSwzKSkKYmVhbnBsb3QocmFyZWZ5SURfeSB+IFJFQUxNLCBkYXRhID0gdHJlbmRzW2ksXSwgd2hhdCA9IGMoMSwxLDEsMSksIGNvbCA9IGMoIiNDQUIyRDYiLCAiIzMzQTAyQyIsICIjQjJERjhBIiksIGJvcmRlciA9ICIjQ0FCMkQ2IiwgeWxhYiA9ICdMYXRpdHVkZSAoZGVnTiknLCBsbCA9IDAuMDUpCmJlYW5wbG90KHRlbXBhdmUgfiBSRUFMTSwgZGF0YSA9IHRyZW5kc1tpLF0sIHdoYXQgPSBjKDEsMSwxLDEpLCBjb2wgPSBjKCIjQ0FCMkQ2IiwgIiMzM0EwMkMiLCAiI0IyREY4QSIpLCBib3JkZXIgPSAiI0NBQjJENiIsIHlsYWIgPSAnVGVtcGVyYXR1cmUgKGRlZ0MpJywgbGwgPSAwLjA1KQpiZWFucGxvdCh0ZW1wYXZlX21ldGFiIH4gUkVBTE0sIGRhdGEgPSB0cmVuZHNbaSxdLCB3aGF0ID0gYygxLDEsMSwxKSwgY29sID0gYygiI0NBQjJENiIsICIjMzNBMDJDIiwgIiNCMkRGOEEiKSwgYm9yZGVyID0gIiNDQUIyRDYiLCB5bGFiID0gJ01ldGFib2xpYyBUZW1wZXJhdHVyZSAoZGVnQyknLCBsbCA9IDAuMDUsIGJ3ID0gJ25yZDAnKSAjIG5yZDAgYmFuZHdpZHRoIHRvIGNhbGN1bGF0aW9uIGdhcApiZWFucGxvdChzZWFzIH4gUkVBTE0sIGRhdGEgPSB0cmVuZHNbaSxdLCB3aGF0ID0gYygxLDEsMSwxKSwgY29sID0gYygiI0NBQjJENiIsICIjMzNBMDJDIiwgIiNCMkRGOEEiKSwgYm9yZGVyID0gIiNDQUIyRDYiLCB5bGFiID0gJ1NlYXNvbmFsaXR5IChkZWdDKScsIGxsID0gMC4wNSkKYmVhbnBsb3QobWljcm9jbGltIH4gUkVBTE0sIGRhdGEgPSB0cmVuZHNbaSxdLCB3aGF0ID0gYygxLDEsMSwxKSwgY29sID0gYygiI0NBQjJENiIsICIjMzNBMDJDIiwgIiNCMkRGOEEiKSwgYm9yZGVyID0gIiNDQUIyRDYiLCB5bGFiID0gJ01pY3JvY2xpbWF0ZXMgKGRlZ0MpJywgbGwgPSAwLjA1KQpiZWFucGxvdCh0ZW1wdHJlbmQgfiBSRUFMTSwgZGF0YSA9IHRyZW5kc1tpLF0sIHdoYXQgPSBjKDEsMSwxLDEpLCBjb2wgPSBjKCIjQ0FCMkQ2IiwgIiMzM0EwMkMiLCAiI0IyREY4QSIpLCBib3JkZXIgPSAiI0NBQjJENiIsIHlsYWIgPSAnVGVtcGVyYXR1cmUgdHJlbmQgKGRlZ0MveXIpJywgbGwgPSAwLjA1KQpiZWFucGxvdChtYXNzX21lYW5fd2VpZ2h0IH4gUkVBTE0sIGRhdGEgPSB0cmVuZHNbaSxdLCB3aGF0ID0gYygxLDEsMSwxKSwgY29sID0gYygiI0NBQjJENiIsICIjMzNBMDJDIiwgIiNCMkRGOEEiKSwgYm9yZGVyID0gIiNDQUIyRDYiLCB5bGFiID0gJ01hc3MgKGcpJywgbGwgPSAwLjA1LCBsb2cgPSAneScpCmJlYW5wbG90KHNwZWVkX21lYW5fd2VpZ2h0ICsxIH4gUkVBTE0sIGRhdGEgPSB0cmVuZHNbaSxdLCB3aGF0ID0gYygxLDEsMSwxKSwgY29sID0gYygiI0NBQjJENiIsICIjMzNBMDJDIiwgIiNCMkRGOEEiKSwgYm9yZGVyID0gIiNDQUIyRDYiLCB5bGFiID0gJ1NwZWVkIChrbS9ociknLCBsbCA9IDAuMDUsIGxvZyA9ICd5JykKYmVhbnBsb3QobGlmZXNwYW5fbWVhbl93ZWlnaHQgfiBSRUFMTSwgZGF0YSA9IHRyZW5kc1tpLF0sIHdoYXQgPSBjKDEsMSwxLDEpLCBjb2wgPSBjKCIjQ0FCMkQ2IiwgIiMzM0EwMkMiLCAiI0IyREY4QSIpLCBib3JkZXIgPSAiI0NBQjJENiIsIHlsYWIgPSAnTGlmZXNwYW4gKHlyKScsIGxsID0gMC4wNSwgbG9nID0gJ3knKQojYmVhbnBsb3QoY29uc2ZyYWMgfiBSRUFMTSwgZGF0YSA9IHRyZW5kc1tpLF0sIHdoYXQgPSBjKDEsMSwxLDEpLCBjb2wgPSBjKCIjQ0FCMkQ2IiwgIiMzM0EwMkMiLCAiI0IyREY4QSIpLCBib3JkZXIgPSAiI0NBQjJENiIsIHlsYWIgPSAnQ29uc3VtZXJzIChmcmFjdGlvbiknLCBsbCA9IDAuMDUsIGxvZyA9ICcnKSAjIHRvbyBzcGFyc2UKI2JlYW5wbG90KGVuZG9mcmFjIH4gUkVBTE0sIGRhdGEgPSB0cmVuZHNbaSxdLCB3aGF0ID0gYygxLDEsMSwxKSwgY29sID0gYygiI0NBQjJENiIsICIjMzNBMDJDIiwgIiNCMkRGOEEiKSwgYm9yZGVyID0gIiNDQUIyRDYiLCB5bGFiID0gJ0VuZG90aGVybXMgKGZyYWN0aW9uKScsIGxsID0gMC4wNSwgbG9nID0gJycpICMgdG9vIHNwYXJzZQpiZWFucGxvdChOc3BwIH4gUkVBTE0sIGRhdGEgPSB0cmVuZHNbaSxdLCB3aGF0ID0gYygxLDEsMSwxKSwgY29sID0gYygiI0NBQjJENiIsICIjMzNBMDJDIiwgIiNCMkRGOEEiKSwgYm9yZGVyID0gIiNDQUIyRDYiLCB5bGFiID0gJ051bWJlciBvZiBzcGVjaWVzJywgbGwgPSAwLjA1LCBsb2cgPSAneScpCmJlYW5wbG90KHRoZXJtYWxfYmlhcyB+IFJFQUxNLCBkYXRhID0gdHJlbmRzW2kgJiAhaXMubmEodGhlcm1hbF9iaWFzKSxdLCB3aGF0ID0gYygxLDEsMSwxKSwgY29sID0gYygiI0NBQjJENiIsICIjMzNBMDJDIiwgIiNCMkRGOEEiKSwgYm9yZGVyID0gIiNDQUIyRDYiLCB5bGFiID0gJ1RoZXJtYWwgYmlhcyAoZGVnQyknLCBsbCA9IDAuMDUpCmJlYW5wbG90KG5wcCB+IFJFQUxNLCBkYXRhID0gdHJlbmRzW2ksXSwgd2hhdCA9IGMoMSwxLDEsMSksIGNvbCA9IGMoIiNDQUIyRDYiLCAiIzMzQTAyQyIsICIjQjJERjhBIiksIGJvcmRlciA9ICIjQ0FCMkQ2IiwgeWxhYiA9ICdOUFAnLCBsbCA9IDAuMDUpCmJlYW5wbG90KHZlZyB+IFJFQUxNLCBkYXRhID0gdHJlbmRzW2kgJiBSRUFMTSAhPSdNYXJpbmUnLF0sIHdoYXQgPSBjKDEsMSwxLDEpLCBjb2wgPSBjKCIjQ0FCMkQ2IiwgIiMzM0EwMkMiLCAiI0IyREY4QSIpLCBib3JkZXIgPSAiI0NBQjJENiIsIHlsYWIgPSAnTlBQJywgbGwgPSAwLjA1KQoKYGBgCgpNYXJpbmUgYXJlIGluIGdlbmVyYWxseSB3YXJtZXIgbG9jYXRpb25zIChzZWF3YXRlciBkb2Vzbid0IGZyZWV6ZSkKTWFyaW5lIGhhdmUgbXVjaCBsb3dlciBzZWFzb25hbGl0eS4KTWFyaW5lIGFuZCBmcmVzaHdhdGVyIGhhdmUgc29tZSB2ZXJ5IHNtYWxsIG1hc3NlcyAocGxhbmt0b24pLCBidXQgbXVjaCBvZiBkYXRhc2V0IGlzIHNpbWlsYXIgdG8gdGVycmVzdHJpYWwuCk1hcmluZSBoYXMgYSBsb3Qgb2Ygc2xvdywgY3Jhd2xpbmcgb3JnYW5pc21zLCBidXQgbGFuZCBoYXMgcGxhbnRzLiBMYW5kIGFsc28gaGFzIGJpcmRzIChmYXN0KS4KCgoKCgoKIyMgUGxvdCB0dXJub3ZlciB2cy4gdGVtcGVyYXR1cmUKYGBge3IgcGxvdCB0dXJub3ZlciB2cyB0ZW1wIHRyZW5kLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0ID0gOCwgZmlnLndpZHRoID0gOSx9CnAxIDwtIGdncGxvdCh0cmVuZHMsIGFlcyh0ZW1wdHJlbmQsIEp0dXRyZW5kLCBjb2xvciA9IFJFQUxNLCBzaXplID0gbnlyQlQpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiKSwgbmEucm0gPSBUUlVFKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKSArIAogIGxhYnMoeCA9ICdUZW1wZXJhdHVyZSB0cmVuZCAowrBDL3lyKScsIHkgPSAnSmFjY2FyZCB0dXJub3ZlciB0ZW1wb3JhbCB0cmVuZCcsIHRpdGxlID0gJ0FsbCcpCgojIEphY2NhcmQgdG90YWwgdHJlbmQgdnMuIHRlbXBlcmF0dXJlIHRyZW5kIChhY3Jvc3MgYWxsIHllYXJzKQpwMiA8LSBnZ3Bsb3QodHJlbmRzLCBhZXModGVtcHRyZW5kLCBKYmV0YXRyZW5kLCBjb2xvciA9IFJFQUxNLCBzaXplID0gbnlyQlQpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiKSwgbmEucm0gPSBUUlVFKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKSArIAogIGxhYnMoeCA9ICdUZW1wZXJhdHVyZSB0cmVuZCAowrBDL3llYXIpJywgeSA9ICdKYWNjYXJkIHRvdGFsIHRlbXBvcmFsIHRyZW5kJykKCiMgSG9ybi1Nb3Jpc2l0YSB0dXJub3ZlciB0cmVuZCB2cy4gdGVtcGVyYXR1cmUgdHJlbmQgKGFjcm9zcyBhbGwgeWVhcnMpCnAzIDwtIGdncGxvdCh0cmVuZHMsIGFlcyh0ZW1wdHJlbmQsIEhvcm50cmVuZCwgY29sb3IgPSBSRUFMTSwgc2l6ZSA9IG55ckJUKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDAuMiwgYWxwaGEgPSAwLjUsIG5hLnJtID0gVFJVRSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnZ2FtJywgZm9ybXVsYSA9IHkgfiBzKHgsIGJzID0gImNzIiksIG5hLnJtID0gVFJVRSkgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlPSJTZXQxIikgKyAKICBsYWJzKHggPSAnVGVtcGVyYXR1cmUgdHJlbmQgKMKwQy95ZWFyKScsIHkgPSAnTW9yaXNpdGEtSG9ybiB0ZW1wb3JhbCB0dXJub3ZlcicpCgojIHNhbWUsIGJ1dCBvbmx5IHRzID49IDUgeXJzCnA0IDwtIGdncGxvdCh0cmVuZHNbbnlyQlQgPj0gNSwgXSwgYWVzKHRlbXB0cmVuZCwgSnR1dHJlbmQsIGNvbG9yID0gUkVBTE0sIHNpemUgPSBueXJCVCkpICsKICBnZW9tX3BvaW50KHNpemUgPSAwLjIsIGFscGhhID0gMC41LCBuYS5ybSA9IFRSVUUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2dhbScsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIpLCBuYS5ybSA9IFRSVUUpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgbGFicyh4ID0gJ1RlbXBlcmF0dXJlIHRyZW5kICjCsEMveXIpJywgeSA9ICdKYWNjYXJkIHR1cm5vdmVyIHRlbXBvcmFsIHRyZW5kJywgdGl0bGUgPSAnPj0gNSB5cnMnKQoKcDUgPC0gZ2dwbG90KHRyZW5kc1tueXJCVCA+PSA1LCBdLCBhZXModGVtcHRyZW5kLCBKYmV0YXRyZW5kLCBjb2xvciA9IFJFQUxNLCBzaXplID0gbnlyQlQpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiKSwgbmEucm0gPSBUUlVFKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKSArIAogIGxhYnMoeCA9ICdUZW1wZXJhdHVyZSB0cmVuZCAowrBDL3llYXIpJywgeSA9ICdKYWNjYXJkIHRvdGFsIHRlbXBvcmFsIHRyZW5kJykKCnA2IDwtIGdncGxvdCh0cmVuZHNbbnlyQlQgPj0gNSwgXSwgYWVzKHRlbXB0cmVuZCwgSG9ybnRyZW5kLCBjb2xvciA9IFJFQUxNLCBzaXplID0gbnlyQlQpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiKSwgbmEucm0gPSBUUlVFKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKSArIAogIGxhYnMoeCA9ICdUZW1wZXJhdHVyZSB0cmVuZCAowrBDL3llYXIpJywgeSA9ICdNb3Jpc2l0YS1Ib3JuIHRlbXBvcmFsIHR1cm5vdmVyJykKCiMgc2FtZSwgYnV0IHJlbW92aW5nIHllYXIgMQpwNyA8LSBnZ3Bsb3QodHJlbmRzLCBhZXModGVtcHRyZW5kLCBKdHV0cmVuZHJlbTAsIGNvbG9yID0gUkVBTE0sIHNpemUgPSBueXJCVCkpICsKICBnZW9tX3BvaW50KHNpemUgPSAwLjIsIGFscGhhID0gMC41LCBuYS5ybSA9IFRSVUUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2dhbScsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIpLCBuYS5ybSA9IFRSVUUpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgbGFicyh4ID0gJ1RlbXBlcmF0dXJlIHRyZW5kICjCsEMveXIpJywgeSA9ICdKYWNjYXJkIHR1cm5vdmVyIHRlbXBvcmFsIHRyZW5kIHcvb3V0IHllYXIgMScsIHRpdGxlID0gJ1dpdGhvdXQgeWVhciAxJykKCnA4IDwtIGdncGxvdCh0cmVuZHMsIGFlcyh0ZW1wdHJlbmQsIEpiZXRhdHJlbmRyZW0wLCBjb2xvciA9IFJFQUxNLCBzaXplID0gbnlyQlQpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiKSwgbmEucm0gPSBUUlVFKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKSArIAogIGxhYnMoeCA9ICdUZW1wZXJhdHVyZSB0cmVuZCAowrBDL3llYXIpJywgeSA9ICdKYWNjYXJkIHRvdGFsIHRlbXBvcmFsIHRyZW5kIHcvb3V0IHllYXIgMScpCgpwOSA8LSBnZ3Bsb3QodHJlbmRzLCBhZXModGVtcHRyZW5kLCBIb3JudHJlbmRyZW0wLCBjb2xvciA9IFJFQUxNLCBzaXplID0gbnlyQlQpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiKSwgbmEucm0gPSBUUlVFKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKSArIAogIGxhYnMoeCA9ICdUZW1wZXJhdHVyZSB0cmVuZCAowrBDL3llYXIpJywgeSA9ICdNb3Jpc2l0YS1Ib3JuIHRlbXBvcmFsIHR1cm5vdmVyIHcvb3V0IHllYXIgMScpCgoKZ3JpZC5hcnJhbmdlKHAxLCBwNCwgcDcsIHAyLCBwNSwgcDgsIHAzLCBwNiwgcDksIG5jb2wgPSAzKQpgYGAKCiMjIyBUaW1lLXNlcmllcyBsZW5ndGggYW5kIHRlbXBlcmF0dXJlIHRyZW5kPwpgYGB7ciB0cyBsZW5ndGggYW5kIHRlbXAgdHJlbmR9CmdncGxvdCh0cmVuZHMsIGFlcyh0ZW1wdHJlbmQsIG55ckJUKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoKSArCiAgc2NhbGVfeV9sb2cxMCgpCmBgYAoKIyMgUGxvdCB0dXJub3ZlciB2cy4gZXhwbGFuYXRvcnkgdmFyaWFibGVzCkxpbmVzIGFyZSBnZ3Bsb3Qgc21vb3RoZXIgZml0cy4KYGBge3IgcGxvdCB0dXJub3ZlciB2IGV4cGxhbmF0b3J5IHZhcnMsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQgPSAxNiwgZmlnLndpZHRoID0gOSx9CgpwMSA8LSBnZ3Bsb3QodHJlbmRzLCBhZXMoUkVBTE0sIEp0dXRyZW5kKSkgKwogIGdlb21fYm94cGxvdChuYS5ybSA9IFRSVUUpICsgCiAgbGFicyh4ID0gJ1JlYWxtJywgeSA9ICdKYWNjYXJkIHR1cm5vdmVyIHRlbXBvcmFsIHRyZW5kJykKCnAyIDwtIGdncGxvdCh0cmVuZHMsIGFlcyh0ZW1wYXZlLCBKdHV0cmVuZCwgc2l6ZSA9IG55ckJUKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gUkVBTE0pLCBzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiKSwgbmEucm0gPSBUUlVFLCBjb2xvciA9ICdibGFjaycpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgbGFicyh4ID0gJ1RlbXBlcmF0dXJlICjCsEMpJywgeSA9ICdKYWNjYXJkIHR1cm5vdmVyIHRlbXBvcmFsIHRyZW5kJykKCnAzIDwtIGdncGxvdCh0cmVuZHMsIGFlcyh0ZW1wYXZlX21ldGFiLCBKdHV0cmVuZCwgc2l6ZSA9IG55ckJUKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gUkVBTE0pLCBzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiKSwgbmEucm0gPSBUUlVFLCBjb2xvciA9ICdibGFjaycpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgbGFicyh4ID0gJ01ldGFib2xpYyB0ZW1wZXJhdHVyZSAowrBDKScsIHkgPSAnSmFjY2FyZCB0dXJub3ZlciB0ZW1wb3JhbCB0cmVuZCcpCgpwNCA8LSBnZ3Bsb3QodHJlbmRzLCBhZXMoc2VhcywgSnR1dHJlbmQsIHNpemUgPSBueXJCVCkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IFJFQUxNKSwgc2l6ZSA9IDAuMiwgYWxwaGEgPSAwLjUsIG5hLnJtID0gVFJVRSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnZ2FtJywgZm9ybXVsYSA9IHkgfiBzKHgsIGJzID0gImNzIiksIG5hLnJtID0gVFJVRSwgY29sb3IgPSAnYmxhY2snKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKSArIAogIGxhYnMoeCA9ICdTZWFzb25hbGl0eSAowrBDKScsIHkgPSAnSmFjY2FyZCB0dXJub3ZlciB0ZW1wb3JhbCB0cmVuZCcpCgpwNSA8LSBnZ3Bsb3QodHJlbmRzLCBhZXMobWljcm9jbGltLCBKdHV0cmVuZCwgc2l6ZSA9IG55ckJUKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gUkVBTE0pLCBzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiKSwgbmEucm0gPSBUUlVFLCBjb2xvciA9ICdibGFjaycpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgc2NhbGVfeF9sb2cxMCgpICsKICBsYWJzKHggPSAnTWljcm9jbGltYXRlIGF2YWlsYWJpbGl0eSAowrBDKScsIHkgPSAnSmFjY2FyZCB0dXJub3ZlciB0ZW1wb3JhbCB0cmVuZCcpCgpwNiA8LSBnZ3Bsb3QodHJlbmRzLCBhZXMobWFzc19tZWFuX3dlaWdodCwgSnR1dHJlbmQsIHNpemUgPSBueXJCVCkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IFJFQUxNKSwgc2l6ZSA9IDAuMiwgYWxwaGEgPSAwLjUsIG5hLnJtID0gVFJVRSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnZ2FtJywgZm9ybXVsYSA9IHkgfiBzKHgsIGJzID0gImNzIiksIG5hLnJtID0gVFJVRSwgY29sb3IgPSAnYmxhY2snKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKSArIAogIHNjYWxlX3hfbG9nMTAoKSArCiAgbGFicyh4ID0gJ01hc3MgKGcpKScsIHkgPSAnSmFjY2FyZCB0dXJub3ZlciB0ZW1wb3JhbCB0cmVuZCcpCgpwNyA8LSBnZ3Bsb3QodHJlbmRzLCBhZXMoc3BlZWRfbWVhbl93ZWlnaHQrMSwgSnR1dHJlbmQsIHNpemUgPSBueXJCVCkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IFJFQUxNKSwgc2l6ZSA9IDAuMiwgYWxwaGEgPSAwLjUsIG5hLnJtID0gVFJVRSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnZ2FtJywgZm9ybXVsYSA9IHkgfiBzKHgsIGJzID0gImNzIiksIG5hLnJtID0gVFJVRSwgY29sb3IgPSAnYmxhY2snKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKSArIAogIHNjYWxlX3hfbG9nMTAoKSArCiAgbGFicyh4ID0gJ1NwZWVkIChrbSAvIGhyKSknLCB5ID0gJ0phY2NhcmQgdHVybm92ZXIgdGVtcG9yYWwgdHJlbmQnKQoKcDggPC0gZ2dwbG90KHRyZW5kcywgYWVzKGxpZmVzcGFuX21lYW5fd2VpZ2h0LCBKdHV0cmVuZCwgc2l6ZSA9IG55ckJUKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gUkVBTE0pLCBzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiKSwgbmEucm0gPSBUUlVFLCBjb2xvciA9ICdibGFjaycpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgc2NhbGVfeF9sb2cxMCgpICsKICBsYWJzKHggPSAnTGlmZXNwYW4gKHlyKSknLCB5ID0gJ0phY2NhcmQgdHVybm92ZXIgdGVtcG9yYWwgdHJlbmQnKQoKcDkgPC0gZ2dwbG90KHRyZW5kcywgYWVzKGNvbnNmcmFjLCBKdHV0cmVuZCwgc2l6ZSA9IG55ckJUKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gUkVBTE0pLCBzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiLCBrID0gMyksIG5hLnJtID0gVFJVRSwgY29sb3IgPSAnYmxhY2snKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKSArIAogIGxhYnMoeCA9ICdGcmFjdGlvbiBjb25zdW1lcnMnLCB5ID0gJ0phY2NhcmQgdHVybm92ZXIgdGVtcG9yYWwgdHJlbmQnKQoKcDEwIDwtIGdncGxvdCh0cmVuZHMsIGFlcyhlbmRvZnJhYywgSnR1dHJlbmQsIHNpemUgPSBueXJCVCkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IFJFQUxNKSwgc2l6ZSA9IDAuMiwgYWxwaGEgPSAwLjUsIG5hLnJtID0gVFJVRSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnZ2FtJywgZm9ybXVsYSA9IHkgfiBzKHgsIGJzID0gImNzIiwgayA9IDMpLCBuYS5ybSA9IFRSVUUsIGNvbG9yID0gJ2JsYWNrJykgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlPSJTZXQxIikgKyAKICBsYWJzKHggPSAnRnJhY3Rpb24gZW5kb3RoZXJtcycsIHkgPSAnSmFjY2FyZCB0dXJub3ZlciB0ZW1wb3JhbCB0cmVuZCcpCgpwMTEgPC0gZ2dwbG90KHRyZW5kcywgYWVzKE5zcHAsIEp0dXRyZW5kLCBzaXplID0gbnlyQlQpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBSRUFMTSksIHNpemUgPSAwLjIsIGFscGhhID0gMC41LCBuYS5ybSA9IFRSVUUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2dhbScsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIpLCBuYS5ybSA9IFRSVUUsIGNvbG9yID0gJ2JsYWNrJykgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlPSJTZXQxIikgKyAKICBzY2FsZV94X2xvZzEwKCkgKwogIGxhYnMoeCA9ICdOdW1iZXIgb2Ygc3BlY2llcycsIHkgPSAnSmFjY2FyZCB0dXJub3ZlciB0ZW1wb3JhbCB0cmVuZCcpCgpwMTIgPC0gZ2dwbG90KHRyZW5kcywgYWVzKHRoZXJtYWxfYmlhcywgSnR1dHJlbmQsIHNpemUgPSBueXJCVCkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IFJFQUxNKSwgc2l6ZSA9IDAuMiwgYWxwaGEgPSAwLjUsIG5hLnJtID0gVFJVRSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnZ2FtJywgZm9ybXVsYSA9IHkgfiBzKHgsIGJzID0gImNzIiksIG5hLnJtID0gVFJVRSwgY29sb3IgPSAnYmxhY2snKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKSArIAogIGxhYnMoeCA9ICdUaGVybWFsIGJpYXMgKMKwQyknLCB5ID0gJ0phY2NhcmQgdHVybm92ZXIgdGVtcG9yYWwgdHJlbmQnKQoKcDEzIDwtIGdncGxvdCh0cmVuZHMsIGFlcyhucHAsIEp0dXRyZW5kLCBzaXplID0gbnlyQlQpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBSRUFMTSksIHNpemUgPSAwLjIsIGFscGhhID0gMC41LCBuYS5ybSA9IFRSVUUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2dhbScsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIpLCBuYS5ybSA9IFRSVUUsIGNvbG9yID0gJ2JsYWNrJykgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlPSJTZXQxIikgKyAKICBzY2FsZV94X2xvZzEwKCkgKwogIGxhYnMoeCA9ICdOZXQgcHJpbWFyeSBwcm9kdWN0aXZpdHkgKG1nIEMgLyBtMiAvIGRheSknLCB5ID0gJ0phY2NhcmQgdHVybm92ZXIgdGVtcG9yYWwgdHJlbmQnKQoKcDE0IDwtIGdncGxvdCh0cmVuZHMsIGFlcyh2ZWcsIEp0dXRyZW5kLCBjb2xvciA9IFJFQUxNLCBzaXplID0gbnlyQlQpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiLCBrID0gNSksIG5hLnJtID0gVFJVRSkgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlPSJTZXQxIikgKyAKICBsYWJzKHggPSAnVmVnZXRhdGlvbiBzY29yZScsIHkgPSAnSmFjY2FyZCB0dXJub3ZlciB0ZW1wb3JhbCB0cmVuZCcpCgpwMTUgPC0gZ2dwbG90KHRyZW5kcywgYWVzKGh1bWFuX2Jvd2xlciwgSnR1dHJlbmQsIGNvbG9yID0gUkVBTE0sIHNpemUgPSBueXJCVCkpICsKICBnZW9tX3BvaW50KHNpemUgPSAwLjIsIGFscGhhID0gMC41LCBuYS5ybSA9IFRSVUUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2dhbScsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIsIGsgPSA1KSwgbmEucm0gPSBUUlVFKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKSArIAogIGxhYnMoeCA9ICdCb3dsZXIgaHVtYW4gaW1wYWN0IHNjb3JlJywgeSA9ICdKYWNjYXJkIHR1cm5vdmVyIHRlbXBvcmFsIHRyZW5kJykKCnAxNiA8LSBnZ3Bsb3QodHJlbmRzLCBhZXMoaHVtYW5fdmVudGVyLCBKdHV0cmVuZCwgY29sb3IgPSBSRUFMTSwgc2l6ZSA9IG55ckJUKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDAuMiwgYWxwaGEgPSAwLjUsIG5hLnJtID0gVFJVRSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnZ2FtJywgZm9ybXVsYSA9IHkgfiBzKHgsIGJzID0gImNzIiwgayA9IDUpLCBuYS5ybSA9IFRSVUUpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgbGFicyh4ID0gJ3NjYWxlZCBIdW1hbiBpbXBhY3Qgc2NvcmUgKFZlbnRlciknLCB5ID0gJ0phY2NhcmQgdHVybm92ZXIgdGVtcG9yYWwgdHJlbmQnKQoKcDE3IDwtIGdncGxvdCh0cmVuZHMsIGFlcyhodW1hbl9oYWxwZXJuLCBKdHV0cmVuZCwgY29sb3IgPSBSRUFMTSwgc2l6ZSA9IG55ckJUKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDAuMiwgYWxwaGEgPSAwLjUsIG5hLnJtID0gVFJVRSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnZ2FtJywgZm9ybXVsYSA9IHkgfiBzKHgsIGJzID0gImNzIiwgayA9IDUpLCBuYS5ybSA9IFRSVUUpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgbGFicyh4ID0gJ3NjYWxlZCBIdW1hbiBpbXBhY3Qgc2NvcmUgKEhhbHBlcm4pJywgeSA9ICdKYWNjYXJkIHR1cm5vdmVyIHRlbXBvcmFsIHRyZW5kJykKCgpncmlkLmFycmFuZ2UocDEsIHAyLCBwMywgcDQsIHA1LCBwNiwgcDcsIHA4LCBwOSwgcDEwLCBwMTEsIHAxMiwgcDEzLCBwMTQsIHAxNSwgcDE2LCBwMTcsIG5jb2wgPSAyKQpgYGAKClN0cm9uZyB0cmVuZHMgd2l0aCB0ZW1wZXJhdHVyZSBjaGFuZ2UsIGJ1dCB0cmVuZHMgYXJlIHByZXR0eSBzeW1tZXRyaWMgYXJvdW5kIG5vIHRyZW5kIGluIHRlbXBlcmF0dXJlLCB3aGljaCBpbXBsaWVzIHdhcm1pbmcgb3IgY29vbGluZyBkcml2ZXMgc2ltaWxhciBkZWdyZWUgb2YgY29tbXVuaXR5IHR1cm5vdmVyLgpTb21lIGluZGljYXRpb24gb2YgbGVzcyB0dXJub3ZlciBmb3IgbGFyZ2VyIG9yZ2FuaXNtcyAobWFzcykKSGlnaGVyIHR1cm5vdmVyIG9uIGxhbmQgd2l0aCBoaWdoZXIgc2Vhc29uYWxpdHk/Ck1vcmUgdHVybm92ZXIgZm9yIHNob3J0ZXItbGl2ZWQgb3JnYW5pc21zPwpObyByZWFsbHkgY2xlYXIgZGlmZmVyZW5jZXMgYW1vbmcgcmVhbG1zLgoKIyMjIFdyaXRlIG91dApgYGB7ciB3cml0ZSBvdXR9CndyaXRlLmNzdih0cmVuZHMsIGd6ZmlsZSgnb3V0cHV0L3R1cm5vdmVyX3dfY292YXJpYXRlcy5jc3YuZ3onKSwgcm93Lm5hbWVzID0gRkFMU0UpCmBgYAoKCiMjIyBVc2VmdWwgdmFyaWFibGVzCmBgYHtyIHVzZWZ1bCB2YXJzfQojIHJlYWxtIHRoYXQgY29tYmluZWQgVGVycmVzdHJpYWwgYW5kIEZyZXNod2F0ZXIsIGZvciBpbnRlcmFjdGluZyB3aXRoIGh1bWFuIGltcGFjdAp0cmVuZHNbLCBSRUFMTTIgOj0gUkVBTE1dCmxldmVscyh0cmVuZHMkUkVBTE0yKSA9IGxpc3QoVGVyckZyZXNoID0gIkZyZXNod2F0ZXIiLCBUZXJyRnJlc2ggPSAiVGVycmVzdHJpYWwiLCBNYXJpbmUgPSAiTWFyaW5lIikKCiMgZ3JvdXAgTWFyaW5lIGludmVydGVicmF0ZXMvcGxhbnRzIGluIHdpdGggQWxsCnRyZW5kc1ssIHRheGFfbW9kMiA6PSB0YXhhX21vZF0KdHJlbmRzW3RheGFfbW9kID09ICdNYXJpbmUgaW52ZXJ0ZWJyYXRlcy9wbGFudHMnLCB0YXhhX21vZDIgOj0gJ0FsbCddCmBgYAoKCiMjIyBMb2ctdHJhbnNmb3JtIHNvbWUgdmFyaWFibGVzLCB0aGVuIGNlbnRlciBhbmQgc2NhbGUuIApgYGAge3IgY2VudGVyIGFuZCBzY2FsZX0KdHJlbmRzWywgdGVtcGF2ZS5zYyA6PSBzY2FsZSh0ZW1wYXZlKV0KdHJlbmRzWywgdGVtcGF2ZV9tZXRhYi5zYyA6PSBzY2FsZSh0ZW1wYXZlX21ldGFiKV0KdHJlbmRzWywgc2Vhcy5zYyA6PSBzY2FsZShzZWFzKV0KdHJlbmRzWywgbWljcm9jbGltLnNjIDo9IHNjYWxlKGxvZyhtaWNyb2NsaW0pKV0KdHJlbmRzWywgdGVtcHRyZW5kLnNjIDo9IHNjYWxlKHRlbXB0cmVuZCwgY2VudGVyID0gRkFMU0UpXQp0cmVuZHNbLCB0ZW1wdHJlbmRfYWJzLnNjIDo9IHNjYWxlKGFicyh0ZW1wdHJlbmQpLCBjZW50ZXIgPSBGQUxTRSldICMgZG8gbm90IGNlbnRlciwgc28gdGhhdCAwIGlzIHN0aWxsIDAgdGVtcGVyYXR1cmUgY2hhbmdlCnRyZW5kc1ssIG1hc3Muc2MgOj0gc2NhbGUobG9nKG1hc3NfbWVhbl93ZWlnaHQpKV0KdHJlbmRzWywgc3BlZWQuc2MgOj0gc2NhbGUobG9nKHNwZWVkX21lYW5fd2VpZ2h0KzEpKV0KdHJlbmRzWywgbGlmZXNwYW4uc2MgOj0gc2NhbGUobG9nKGxpZmVzcGFuX21lYW5fd2VpZ2h0KSldCnRyZW5kc1ssIGNvbnN1bWVyZnJhYy5zYyA6PSBzY2FsZShjb25zZnJhYyldCnRyZW5kc1ssIGVuZG90aGVybWZyYWMuc2MgOj0gc2NhbGUoZW5kb2ZyYWMpXQp0cmVuZHNbLCBuc3BwLnNjIDo9IHNjYWxlKGxvZyhOc3BwKSldCnRyZW5kc1ssIHRoZXJtYWxfYmlhcy5zYyA6PSBzY2FsZSh0aGVybWFsX2JpYXMpXQp0cmVuZHNbLCBucHAuc2MgOj0gc2NhbGUobG9nKG5wcCkpXQp0cmVuZHNbLCB2ZWcuc2MgOj0gc2NhbGUobG9nKHZlZysxKSldCnRyZW5kc1ssIGh1bWFuX2Jvd2xlci5zYyA6PSBzY2FsZShsb2coaHVtYW5fYm93bGVyKzEpKSwgYnkgPSBSRUFMTTJdICMgc2VwYXJhdGUgc2NhbGluZyBieSByZWFsbQp0cmVuZHNbUkVBTE0yID09ICdUZXJyRnJlc2gnLCBodW1hbl9mb290cHJpbnQuc2MgOj0gc2NhbGUobG9nKGh1bWFuX3ZlbnRlcisxKSldCnRyZW5kc1tSRUFMTTIgPT0gJ01hcmluZScsIGh1bWFuX2Zvb3RwcmludC5zYyA6PSBzY2FsZShsb2coaHVtYW5faGFscGVybikpXQpgYGAKCgojIyMgRG8gdGhlIHZhcmlhYmxlcyBsb29rIG9rPwojIyMjIFVuc2NhbGVkCmBgYHtyIGhpc3RvZ3JhbXMgdW5zY2FsZWQsIGZpZy5oZWlnaHQgPSA5fQojIGhpc3RvZ3JhbXMgdG8gZXhhbWluZQpjZXhtYWluID0gMC42CnBhcihtZnJvdyA9IGMoNSw0KSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QobWlueXJCVCwgbWFpbiA9ICdTdGFydCB5ZWFyJywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCmludmlzaWJsZSh0cmVuZHNbLCBoaXN0KG1heHlyQlQgLSBtaW55ckJULCBtYWluID0gJ0R1cmF0aW9uICh5ZWFycyknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QobnlyQlQsIG1haW4gPSAnTnVtYmVyIG9mIHNhbXBsZWQgeWVhcnMnLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QobWFzc19tZWFuX3dlaWdodCwgbWFpbiA9ICdNYXNzIChnKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdChzcGVlZF9tZWFuX3dlaWdodCwgbWFpbiA9ICdTcGVlZCAoa20vaHIpJywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCmludmlzaWJsZSh0cmVuZHNbLCBoaXN0KGxpZmVzcGFuX21lYW5fd2VpZ2h0LCBtYWluID0gJ0xpZmVzcGFuICh5ciknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QodGVtcGF2ZV9tZXRhYiwgbWFpbiA9ICdNZXRhYm9saWMgdGVtcGVyYXR1cmUgKMKwQyknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QoY29uc2ZyYWMsIG1haW4gPSAnQ29uc3VtZXJzIChmcmFjdGlvbiknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QoZW5kb2ZyYWMsIG1haW4gPSAnRW5kb3RoZXJtcyAoZnJhY3Rpb24pJywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCmludmlzaWJsZSh0cmVuZHNbLCBoaXN0KHRlbXBhdmUsIG1haW4gPSAnRW52aXJvbm1lbnRhbCB0ZW1wZXJhdHVyZSAowrBDKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdCh0ZW1wdHJlbmQsIG1haW4gPSAnVGVtcGVyYXR1cmUgdHJlbmQgKMKwQy95ciknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3Qoc2VhcywgbWFpbiA9ICdTZWFzb25hbGl0eSAowrBDKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdChtaWNyb2NsaW0sIG1haW4gPSAnTWljcm9jbGltYXRlcyAowrBDKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdChOc3BwLCBtYWluID0gJ1NwZWNpZXMgcmljaG5lc3MnLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QodGhlcm1hbF9iaWFzLCBtYWluID0gJ1RoZXJtYWwgYmlhcyAowrBDKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdChucHAsIG1haW4gPSAnTmV0IHByaW1hcnkgcHJvZHVjdGl2aXR5JywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCmludmlzaWJsZSh0cmVuZHNbLCBoaXN0KHZlZywgbWFpbiA9ICdWZWdldGF0aW9uIGluZGV4JywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCmludmlzaWJsZSh0cmVuZHNbLCBoaXN0KGh1bWFuX2Jvd2xlciwgbWFpbiA9ICdIdW1hbiBpbXBhY3Qgc2NvcmUgKEJvd2xlciknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QoaHVtYW5fdmVudGVyLCBtYWluID0gJ0h1bWFuIGltcGFjdCBzY29yZSAoVmVudGVyKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdChodW1hbl9oYWxwZXJuLCBtYWluID0gJ0h1bWFuIGltcGFjdCBzY29yZSAoSGFscGVybiknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKCmBgYAoKIyMjIyBTY2FsZWQKYGBge3IgaGlzdG9ncmFtcyBzY2FsZWQsIGZpZy5oZWlnaHQgPSA5fQojIGhpc3RvZ3JhbXMgdG8gZXhhbWluZQpjZXhtYWluID0gMC42CnBhcihtZnJvdyA9IGMoNSw0KSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QodGVtcGF2ZS5zYywgbWFpbiA9ICdFbnZpcm9ubWVudGFsIHRlbXBlcmF0dXJlICjCsEMpJywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCmludmlzaWJsZSh0cmVuZHNbLCBoaXN0KHRlbXBhdmVfbWV0YWIuc2MsIG1haW4gPSAnTWV0YWJvbGljIHRlbXBlcmF0dXJlICjCsEMpJywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCmludmlzaWJsZSh0cmVuZHNbLCBoaXN0KHNlYXMuc2MsIG1haW4gPSAnU2Vhc29uYWxpdHkgKMKwQyknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QobWljcm9jbGltLnNjLCBtYWluID0gJ2xvZyBNaWNyb2NsaW1hdGVzICjCsEMpJywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCmludmlzaWJsZSh0cmVuZHNbLCBoaXN0KHRlbXB0cmVuZC5zYywgbWFpbiA9ICdUZW1wZXJhdHVyZSB0cmVuZCAowrBDL3lyKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdCh0ZW1wdHJlbmRfYWJzLnNjLCBtYWluID0gJ2FicyhUZW1wZXJhdHVyZSB0cmVuZCkgKMKwQy95ciknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QobWFzcy5zYywgbWFpbiA9ICdsb2cgTWFzcyAoZyknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3Qoc3BlZWQuc2MsIG1haW4gPSAnbG9nIFNwZWVkIChrbS9ociknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QobGlmZXNwYW4uc2MsIG1haW4gPSAnbG9nIExpZmVzcGFuICh5ciknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QoY29uc3VtZXJmcmFjLnNjLCBtYWluID0gJ0NvbnN1bWVycyAoZnJhY3Rpb24pJywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCmludmlzaWJsZSh0cmVuZHNbLCBoaXN0KGVuZG90aGVybWZyYWMuc2MsIG1haW4gPSAnRW5kb3RoZXJtcyAoZnJhY3Rpb24pJywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCmludmlzaWJsZSh0cmVuZHNbLCBoaXN0KG5zcHAuc2MsIG1haW4gPSAnbG9nIFNwZWNpZXMgcmljaG5lc3MnLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QodGhlcm1hbF9iaWFzLnNjLCBtYWluID0gJ1RoZXJtYWwgYmlhcyAowrBDKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdChucHAuc2MsIG1haW4gPSAnbG9nIE5ldCBwcmltYXJ5IHByb2R1Y3Rpdml0eScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdCh2ZWcuc2MsIG1haW4gPSAnbG9nIFZlZ2V0YXRpb24gaW5kZXgnLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QoaHVtYW5fYm93bGVyLnNjLCBtYWluID0gJ2xvZyBIdW1hbiBpbXBhY3Qgc2NvcmUgKEJvd2xlciknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QoaHVtYW5fZm9vdHByaW50LnNjLCBtYWluID0gJ2xvZyBIdW1hbiBpbXBhY3Qgc2NvcmUgKFZlbnRlciAmIEhhbHBlcm4pJywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCgpgYGAKCgoKIyMjIENoZWNrIGNvcnJlbGF0aW9ucyBhbW9uZyB2YXJpYWJsZXMuIFBlYXJzb24ncyByIGlzIG9uIHRoZSBsb3dlciBkaWFnb25hbC4KYGBge3IgcGFpcnMsIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xMH0KcGFuZWwuY29yIDwtIGZ1bmN0aW9uKHgsIHksIGRpZ2l0cyA9IDIsIHByZWZpeCA9ICIiLCBjZXguY29yLCAuLi4pCnsKICAgIHVzciA8LSBwYXIoInVzciIpOyBvbi5leGl0KHBhcih1c3IpKQogICAgcGFyKHVzciA9IGMoMCwgMSwgMCwgMSkpCiAgICByIDwtIGNvcih4LCB5LCB1c2UgPSAncGFpcndpc2UuY29tcGxldGUub2JzJykKICAgIHR4dCA8LSBmb3JtYXQoYyhyLCAwLjEyMzQ1Njc4OSksIGRpZ2l0cyA9IGRpZ2l0cylbMV0KICAgIHR4dCA8LSBwYXN0ZTAocHJlZml4LCB0eHQpCiAgICBpZihtaXNzaW5nKGNleC5jb3IpKSBjZXguY29yIDwtIDAuOC9zdHJ3aWR0aCh0eHQpCiAgICB0ZXh0KDAuNSwgMC41LCB0eHQpICMsIGNleCA9IGNleC5jb3IgKiByKQp9CnBhaXJzKGZvcm11bGEgPSB+IHRlbXBhdmUuc2MgKyB0ZW1wYXZlX21ldGFiLnNjICsgc2Vhcy5zYyArIG1pY3JvY2xpbS5zYyArIHRlbXB0cmVuZC5zYyArIHRlbXB0cmVuZF9hYnMuc2MgKyBtYXNzLnNjICsgc3BlZWQuc2MgKyBsaWZlc3Bhbi5zYyArIGNvbnN1bWVyZnJhYy5zYyArIGVuZG90aGVybWZyYWMuc2MgKyBuc3BwLnNjICsgdGhlcm1hbF9iaWFzLnNjICsgbnBwLnNjICsgdmVnLnNjICsgaHVtYW5fYm93bGVyLnNjICsgaHVtYW5fZm9vdHByaW50LnNjLCBkYXRhID0gdHJlbmRzLCBnYXAgPSAxLzEwLCBjZXggPSAwLjIsIGNvbCA9ICcjMDAwMDAwMjInLCBsb3dlci5wYW5lbCA9IHBhbmVsLmNvcikKCmBgYAoKTWFzcyBhbmQgbGlmZXNwYW4gbG9vayB0aWdodGx5IGNvcnJlbGF0ZWQsIGJ1dCByIG9ubHkgMC41Ni4uLj8KVGVtcGF2ZV9tZXRhYiBhbmQgbGlmZXNwYW4gZG9uJ3QgbG9vayB0aWdodGx5IGNvcnJlbGF0ZWQsIGJ1dCByPSAtMC44MSAKVGVtcGF2ZV9tZXRhYiBhbmQgc3BlZWQgZG9uJ3QgbG9vayB0aWdodGx5IGNvcnJlbGF0ZWQsIGJ1dCByPSAtMC44MyAKTGlmZXNwYW4gYW5kIHNwZWVkIGRvbid0IGxvb2sgdGlnaHRseSBjb3JyZWxhdGVkLCBidXQgciA9IDAuNzMK